package com.qcby.llmtchstd.utils;

import okhttp3.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class LLMClient {
    // 替换为你的 API Key
    private static final String API_KEY = "Bearer sk-81185568f0824b618a395d855e7e3ef4";
    private static final String API_URL = "https://api.deepseek.com/chat/completions";

    // 静态客户端实例
    private static final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(120, TimeUnit.SECONDS)
            .writeTimeout(15, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .build();

    /**
     * 调用大模型API获取回复（使用默认格式指令）
     * @param userMessage 用户输入的消息
     * @return 大模型返回的响应字符串（JSON格式）
     * @throws IOException 网络请求异常
     */
    public static String getLLMResponse(String userMessage) throws IOException {
        // 默认格式指令
        String formatInstruction = "\n请用纯文本回答，不要使用任何 Markdown 格式（如 **、-、### 等符号），用自然分段和换行展示，标题后用冒号，列表项用中文序号（1. 2. ）或顿号。\n" +
                "\n" +
                "回答时语言需简洁易懂，符合师生日常沟通的口语化表达习惯，避免使用过于专业或生僻的术语。针对学生提问，要注重引导思考，可适当加入启发式提问或结合生活、学习中的常见例子进行说明，帮助学生理解知识点；如果涉及作业相关问题，需先提醒学生独立思考，再提供解题思路或关键步骤提示，不直接给出完整答案。\n" +
                "\n" +
                "针对老师提问，可侧重提供系统性的教学思路、知识点延伸资料或课堂互动设计建议，方便教学使用；若老师询问学情分析、教学方法等内容，回答需结合教学规律，给出具体且可操作的建议。\n" +
                "\n" +
                "无论面对老师还是学生，回答需保证学科知识的准确性；遇到不确定的知识点，应明确说明并建议查阅教材、教辅资料等权威来源。回答需积极正面，对师生的疑问耐心回应；若问题超出学科辅助、教学支持等范围，应礼貌说明无法提供相关帮助。";
        return getLLMResponseWithInstruction(userMessage, formatInstruction);
    }

    /**
     * 调用大模型API获取回复（使用自定义格式指令）
     * @param userMessage 用户输入的消息
     * @param formatInstruction 自定义格式要求
     * @return 大模型返回的响应字符串（JSON格式）
     * @throws IOException 网络请求异常
     */
    public static String getLLMResponse2(String userMessage, String formatInstruction) throws IOException {
        String appendedConstraint = "\n特别补充：返回结果中绝对不允许包含```json、```等任何格式标记，仅返回纯JSON字符串本身，无需任何额外说明或标记。";
        String fullInstruction = formatInstruction + appendedConstraint;
        return getLLMResponseWithInstruction(userMessage, fullInstruction);
    }

    /**
     * 核心方法：复用请求逻辑，接收用户消息和格式指令
     */
    private static String getLLMResponseWithInstruction(String userMessage, String formatInstruction) throws IOException {
        // 1. 拼接用户消息和格式要求
        String fullMessage = userMessage + formatInstruction;

        // 2. 对消息进行JSON转义
        String escapedMessage = escapeJson(fullMessage);

        // 3. 构建请求体JSON
        String jsonBody = String.format("{\n" +
                "    \"model\": \"deepseek-chat\",\n" +
                "    \"messages\": [\n" +
                "        {\"role\": \"user\", \"content\": \"%s\"}\n" +
                "    ],\n" +
                "    \"temperature\": 0.7,\n" +
                "    \"top_p\": 0.8\n" +
                "}", escapedMessage);

        // 4. 创建请求
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"),
                jsonBody
        );

        Request request = new Request.Builder()
                .url(API_URL)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "application/json")
                .addHeader("Authorization", API_KEY)
                .build();

        // 5. 发送请求并返回响应
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                String errorBody = response.body() != null ? response.body().string() : "无错误信息";
                throw new IOException("API调用失败: " + response.code() + " " + response.message() + ", 详情: " + errorBody);
            }
            return response.body().string();
        }
    }

    /**
     * JSON特殊字符转义方法
     */
    private static String escapeJson(String input) {
        if (input == null) {
            return "";
        }
        return input.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }
}
